package com.gitee.wsl.compose.chart.legend

//package io.github.koalaplot.core.legend


import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.onClick
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntSize
import com.gitee.wsl.compose.chart.KoalaPlotTheme
import com.gitee.wsl.compose.chart.SelectChangedListener
import com.gitee.wsl.compose.chart.SelectCheck
import com.gitee.wsl.compose.modifier.state.drawSelectBorder
import kotlin.math.max



/**
 * A flow layout type of legend where each entry will take as much horizontal space as it requires,
 * up to the maximum width of the component. Multiple legend entries will be placed in the same
 * row until all horizontal space is consumed.
 */
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Legend.Flow(
    itemCount: Int,
    symbol: LegendSymbolSlate = Legend.defaultLegendSymbolSlate,
    label:LegendLabelSlate =  Legend.defaultLegendLabelSlate,
    symbolGap: Dp = KoalaPlotTheme.plotSizes.gap,
    columnGap: Dp = KoalaPlotTheme.plotSizes.gap,
    rowGap: Dp = KoalaPlotTheme.plotSizes.gap,
    selectCheck: SelectCheck = { false },
    selectChangedListener: SelectChangedListener? = null,
    modifier: Modifier = Modifier
) {
    fun Density.sizeOrPlace(
        placeables: List<Placeable>,
        constraints: Constraints,
        place: Placeable.(Int, Int) -> Unit
    ): IntSize {
        var x = 0
        var y = 0
        var rowHeight = 0
        var width = 0 // total width

        for (i in 0 until itemCount) {
            placeables[i].place(x, y)
            rowHeight = max(rowHeight, placeables[i].height)
            x += placeables[i].width + columnGap.roundToPx()

            if (i == itemCount - 1 ||
                x + placeables[i + 1].width > constraints.maxWidth
            ) { // last item or next item will exceed horizontal size -> end of row
                width = max(width, x - columnGap.roundToPx())
                x = 0
                y += rowGap.roundToPx() + rowHeight
                rowHeight = 0
            }
        }

        return IntSize(width, y - rowGap.roundToPx())
    }

    Layout(modifier = modifier.clipToBounds(), content = {
        for (i in 0 until itemCount) {
            val selected = selectCheck.invoke(i)
            Row(modifier = Modifier.onClick{selectChangedListener?.invoke(i)}.drawSelectBorder(selected,drawLeft = true)) {
                Box(modifier = Modifier.align(Alignment.CenterVertically)) {
                    legendScopeInstance.symbol(i,selected)
                }
                Spacer(modifier = Modifier.size(symbolGap))
                Box(modifier = Modifier.align(Alignment.CenterVertically)) {
                    legendScopeInstance.label(i,selected,selectChangedListener)
                }
            }
        }
    }) { measureables, constraints ->
        val placeables = measureables.map { it.measure(constraints) }

        val size = sizeOrPlace(placeables, constraints) { _, _ -> }

        layout(size.width, size.height) {
            sizeOrPlace(placeables, constraints) { x, y -> this.place(x, y) }
        }
    }
}
